﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QDasTransfer.Classes
{
    /// <summary>
    /// 用于处理文件路径。
    /// 用法: FilePath fi = FilePath.Parse("c:\\data\\file1.xml");
    /// 注：FilePath 为只读（类似于String）。
    /// </summary>
    public class FilePath
    {
        /// <summary>
        /// 当前路径是否为文件夹。
        /// </summary>
        public bool IsDirectory { get; set; }

        /// <summary>
        /// 文件全路径，包括文件名，如：C:\abc\bbc.txt。
        /// </summary> 
        public string FullPath { get; set; }

        /// <summary>
        /// 文件名，不包括路径和扩展名，如C:\abc\bbc.txt的文件名是 bbc。
        /// </summary>
        public string Filename { get; set; }

        /// <summary>
        /// 每一级路径的名称，如输入为 C:\abc\bbc.txt，则返回 ["C:", "abc"]
        /// </summary>
        public string[] DirNames { get; set; }

        /// <summary>
        /// 扩展名(首位为点)。
        /// </summary>
        public string Extention { get; set; }

        /// <summary>
        /// 全路径名称，不包括文件名，如  C:\abc\bbc.txt，则返回 C:\abc
        /// </summary>
        public string FullDirectory { get; set; }

        /// <summary>
        /// 当前工作路径，如C:\abc\bbc.txt，则此值为abc
        /// </summary>
        public string CurrentDirectory { get; set; }

        /// <summary>
        /// 目录的最后一个名称，如C:\abc\bbc.txt，则此值为C:。若不存在，则为 null。
        /// </summary>
        public string ParentDirectory { get; set; }

        /// <summary>
        /// 路径的根名称，如 C:\abc\bbc.txt 的根为 C:
        /// </summary>
        public string GetRoot() { return DirNames[0]; }

        /// <summary>
        /// 文件的深度，根目录为1开始。如 C:\abc\bbc.txt 的深度为2。
        /// </summary>
        public int Depth { get; set; }


        /// <summary>
        /// 此构造函数仅限私用，函数提供了唯一的方法 Parse() 用于新建对象。
        /// </summary>
        private FilePath() { }

        /// <summary>
        /// 返回文件夹下的所有子文件。
        /// </summary>
        /// <returns></returns>
        public List<FilePath> GetFiles()
        {
            List<FilePath> filepaths = new List<FilePath>();
            foreach (string file in System.IO.Directory.GetFiles(FullPath))
            {
                filepaths.Add(FilePath.ParseFile(file));
            }
            return filepaths;
        }

        /// <summary>
        /// 返回当前目录下的所有子目录。
        /// </summary>
        /// <returns></returns>
        public List<FilePath> GetDirectories()
        {
            List<FilePath> filepaths = new List<FilePath>();
            foreach (string file in System.IO.Directory.GetDirectories(FullPath))
            {
                filepaths.Add(FilePath.ParseFile(file));
            }
            return filepaths;
        }

        /// <summary>
        /// 根据输入路径解析，如果解析出错，返回为 null。
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static FilePath ParseFile(string filePath)
        {
            FilePath fi = new FilePath();
            try
            {
                fi.IsDirectory = false;
                fi.FullPath = filePath;
                fi.Filename = Path.GetFileNameWithoutExtension(filePath);
                fi.Extention = Path.GetExtension(filePath);
                fi.FullDirectory = Path.GetDirectoryName(filePath);
                fi.DirNames = fi.FullDirectory.Split('\\');
                fi.Depth = fi.DirNames.Length - 1;
                fi.CurrentDirectory = fi.DirNames[fi.DirNames.Length - 1];
                fi.ParentDirectory = fi.DirNames.Length > 1 ? fi.DirNames[fi.DirNames.Length - 2] : null;
            }
            catch
            {
                fi = null;
            }

            return fi;
        }

        /// <summary>
        /// 根据输入路径解析，如果解析出错，返回为 null。
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static FilePath ParseDirectory(string filePath)
        {
            FilePath fi = new FilePath();
            try
            {
                fi.IsDirectory = true;
                fi.FullPath = filePath;
                fi.Filename = "";
                fi.Extention = "";
                fi.FullDirectory = Path.GetDirectoryName(filePath);
                fi.DirNames = fi.FullDirectory.Split('\\');
                fi.Depth = fi.DirNames.Length - 1;
                fi.CurrentDirectory = fi.DirNames[fi.DirNames.Length - 1];
                fi.ParentDirectory = fi.DirNames.Length > 1 ? fi.DirNames[fi.DirNames.Length - 2] : null;
            }
            catch
            {
                fi = null;
            }

            return fi;
        }

        /// <summary>
        /// 文件是否存在。
        /// </summary>
        /// <returns></returns>
        public bool Existed()
        {
            return IsDirectory ? System.IO.Directory.Exists(FullPath) : File.Exists(FullPath);
        }

        /// <summary>
        /// 将str追加至文件名末尾，并返回一个新的FilePath对象。如 C:\abc\bbc.txt 追加 _1，返回 C:\abc\bbc_1.txt。
        /// 注：目前仅支付对文件操作，如果是文件夹则返回为自身的复制。
        /// </summary>
        /// <param name="inputfile"></param>
        /// <returns></returns>
        public FilePath Append(string str)
        {
            return IsDirectory ?
                FilePath.ParseDirectory(FullPath) :
                FilePath.ParseFile(Path.Combine(FullDirectory, Filename + str, Extention)); ;
        }

        /// <summary>
        /// 将str追加至文件名首，并返回一个新的FilePath对象。如 C:\abc\bbc.txt 追加 fx_，返回 C:\abc\fx_bbc.txt。
        /// 注：目前仅支付对文件操作，如果是文件夹则返回为自身的复制。
        /// </summary>
        /// <param name="inputfile"></param>
        /// <returns></returns>
        public FilePath Prepend(string str)
        {
            return IsDirectory ?
               FilePath.ParseDirectory(FullPath) :
               FilePath.ParseFile(Path.Combine(FullDirectory, str + Filename, Extention)); ;
        }



        /// <summary>
        /// Adds a four-digit id to the filename in front of its extention.
        /// </summary>
        /// <param name="outputfile"></param>
        /// <returns></returns>
        public FilePath AddIncreamentId()
        {
            int suffixid = 0;
            string outputfile = null;
            while (File.Exists(outputfile))
            {
                suffixid++;
                outputfile = string.Format("{0}\\{1}_{2}{3}", FullDirectory, Filename, suffixid.ToString("0000"), Extention);
            }

            return FilePath.ParseFile(outputfile);
        }
    }
}
